/**
 * 实现范例，可根据注释介绍自行实现 provider
 * 您可以自由实现几乎所有线上/本地提供商聊天功能，provider 功能还在不断补充完善中
 *
 * 本项目内置了一些实用工具，可查看 /src/provider/llm/hooks/utils
 * 注意：本文件仅供示例说明，请勿使用
 */
import type { LLMAttachCheckRes, LLMCompletionsData, LLMCompletionsCb } from '@/provider/llm/type'
import { llmBaseProvider } from '@/provider/llm/baseProvider'

// 定义的 class，必须实现抽象类 llmBaseProvider 中的功能
class ExampleProvider extends llmBaseProvider {
  protected init() {
    // 初始化方法，用于new api实例
    // 有以下参数可以使用：
    // baseUrl       - API地址，基础访问地址（通过 this.getBaseUrl() 获取）
    // apiKey        - API密钥，避免在前端代码中明文引用，如需使用建议加密（通过 this.getApiKey() 获取）
    // defaultModels - 固定配置的模型模型，未配置返回空数组（通过 this.getDefaultModels() 获取）
  }

  public async accessCheck() {
    // 该方法用于检测是否能正确访问服务器，返回布尔值
    // 若服务器未单独提供检测方法，可访问通用 API 进行判断，建议选择不消耗 tokens 的请求
    return false
  }

  public attachCheck(model: LLMModel): LLMAttachCheckRes {
    // 根据传入的模型判断并返回附件支持情况，返回包含如下内容（参数都是可选）：
    // allowVision - 是否支持上传图片
    // visionLimit - 上传图片总文件大小（字节），默认不限
    // allowDoc    - 是否支持上传文档
    // docLimit    - 上传文档单个文件大小（字节），默认不限
    // docsAccept  - 支持的文档 mimes，允许上传文档时请填写
    // 当 allowVision 和 allowDocs 都为 false 时，表示不支持附件功能
    return {
      allowVision: !!model.vision,
      visionLimit: 20 * 1024 * 1024,
      allowDoc: true,
      docLimit: 20 * 1024 * 1024,
      docsAccept: ['application/pdf', 'text/plain'],
    }
  }

  public async getModels() {
    // 读取可用的模型列表，按照标准格式返回
    // 如果从配置中定义了 defaultModels，需要在此处处理才会使其生效
    const response: LLMModel[] = []
    return response
  }

  public async geneTitle(model: string, messages: LLMMessage[]) {
    // 通过聊天历史生成标题，仅会在新聊天的第一次响应后调用
    // 可自由选择标题生成方式，如：内容截取、模型调用、API生成等
    console.log(model, messages)
    // 返回空表示生成失败，调用时不会更新（保留原标题）
    return ''
  }

  public async completions(data: LLMCompletionsData, callback: LLMCompletionsCb) {
    // 聊天补全调用，data为请求所需的完整参数（目前所有请求都默认stream，如有其它需求可自行扩展）

    // 可以通过 data.messages 中的 attachs 判断是否需要进行图片处理
    // 对于图片数据，目前 url 为 base64 格式图片信息，可直接使用

    // 可执行 callback 中三种回调方法
    // 1. onUpdate。每次执行 SSE 返回文本片段时调用，响应当前片段与之前的完整文本内容
    // 2. onSuccess。成功时调用，响应全部完整文本
    // 3. onError。失败时调用，响应失败内容
    // 方法中需要处理打断逻辑

    callback.onError(new Error('The Example Provider is not provide cmpletions!'))
  }

  public async abort() {
    // 通过外部执行打断方法
    // 打断 completions() 的执行
  }
}

export default ExampleProvider
